/**
 * @file pwm.c
 * @author LuoJing
 * @version 1.0
 * @date 2018-09-14
 * @brief YC pwm api
 * @details Includes PWM clock selection, IO selection, parameter configuration
 */
 
#include "include.h"
#include "pwm.h"


void YC_PWMInitClock()
{
	REG8(ADDR_PWM_CLK_SEL) &= ~(0x11 << 6);
	REG8(ADDR_PWM_CLK_SEL) |= 1 << 6;				//select PWM clock: system clock undivided 48Mhz
	REG8(ADDR_CLK_OFF2) &= ~(1 << PWM_CLOCK);	//turn on PWM clock
}

void YC_PWMCloseClock()
{	
	REG8(ADDR_CLK_OFF2) |= 1 << PWM_CLOCK;	//turn off PWM clock	
}

/*
void YC_PWMConfig(YC_PWMChanel_e PWMChSel, u32_t PWM_Freq, u32_t Duty)
{
	u32_t pwm_count_max = 48000000 / PWM_Freq;
	u16_t PWM_pcnt = 0;
	u16_t PWM_ncnt = 0;
	PWM_pcnt = pwm_count_max * Duty / 100;
	PWM_ncnt = pwm_count_max - PWM_pcnt;	

	switch(PWMChSel){
	case PWM_CH0:
		REG_PWM_PCOUNT(0) = PWM_pcnt & 0xff;
		*(&REG_PWM_PCOUNT(0)+1) = PWM_pcnt >> 8 & 0xff;		//set positive pulse clock count
		REG_PWM_NCOUNT(0) = PWM_ncnt & 0xff;				
		*(&REG_PWM_NCOUNT(0)+1) = PWM_ncnt >> 8 & 0xff;		//set npositive pulse clock count
	break;
	case PWM_CH1:
		REG_PWM_PCOUNT(1) = PWM_pcnt & 0xff;
		*(&REG_PWM_PCOUNT(1)+1) = PWM_pcnt >> 8 & 0xff;	    //set positive pulse clock count
		REG_PWM_NCOUNT(1) = PWM_ncnt & 0xff;
		*(&REG_PWM_NCOUNT(1)+1) = PWM_ncnt >> 8 & 0xff;	    //set npositive pulse clock count
		break;
	default:
		break;
	}
}
*/


void YC_PWMConfig(PWM_Set *PwmConfig)
{
	switch(PwmConfig->channal){
	case PWM_CH0:		
		REG8(ADDR_PWM_PCOUNT) = PwmConfig->pcnt & 0xff;
		*(&REG8(ADDR_PWM_PCOUNT)+1) = PwmConfig->pcnt >> 8 & 0xff;		//set positive pulse clock count
		REG8(ADDR_PWM_NCOUNT) = PwmConfig->ncnt & 0xff;				
		*(&REG8(ADDR_PWM_NCOUNT)+1) =  PwmConfig->ncnt >> 8 & 0xff;		//set npositive pulse clock count
		break;
	case PWM_CH1:
		REG8(ADDR_PWM_PCOUNT2) = PwmConfig->pcnt & 0xff;
		*(&REG8(ADDR_PWM_PCOUNT2)+1) = PwmConfig->pcnt >> 8 & 0xff;	    //set positive pulse clock count
		REG8(ADDR_PWM_NCOUNT2) =  PwmConfig->ncnt & 0xff;
		*(&REG8(ADDR_PWM_NCOUNT2)+1) =  PwmConfig->ncnt >> 8 & 0xff;	    //set npositive pulse clock count
		break;
	default:
		break;
	}		
}

void YC_PWMEnableChanel(YC_PWMChanel_e PWMChSel)
{
  	switch(PWMChSel){
	case PWM_CH0:
		REG8(ADDR_PWM_ENABLE) |= 1 << 6;
		break;
	case PWM_CH1:
		REG8(ADDR_PWM_ENABLE) |= 1 << 7;
			break;
	default:
		break;
	}
}

void YC_PWMDisableChanel(YC_PWMChanel_e PWMChSel)
{
  	switch(PWMChSel){
	case PWM_CH0:
		REG8(ADDR_PWM_ENABLE) &= ~(1 << 6);
		break;
	case PWM_CH1:
		REG8(ADDR_PWM_ENABLE) &= ~(1 << 7);
			break;
	default:
		break;
	}
}

void YC_PWMOpenChanel(YC_PWMChanel_e PWMChSel, u8_t gpio)
{
	u8_t lebit = 7;
	switch(PWMChSel){
	case PWM_CH0:
		switch(gpio){									        //open PWM0 output pin
			case 4:
				REG8(ADDR_REG_GPIO_SEL1) |= 1 << 6;
				break;
			case 3:
				lebit--;
			case 6:
				lebit--;
			case 7:
				lebit--;
			case 18:
				lebit--;
			case 19:
				lebit--;
			case 20:
				lebit--;
			case 21:
				lebit--;
			case 22:
				REG8(ADDR_REG_GPIO_SEL2) |= 1 << lebit;		  
				break;
			default:
				break;
		}
		break;
	case PWM_CH1:
		REG8(ADDR_REG_GPIO_SEL1) |= 1 << 7;					        //open PWM1 output pin
		break;
	default:
		break;
	}
}

void YC_PWMCloseChanel(u8_t gpio)
{
	u8_t lebit = 7;

	switch(gpio){
		case 5:
			REG8(ADDR_REG_GPIO_SEL1) &= ~(1 << 7);				//close PWM1 output pin
			break;			
		case 4:													//close PWM0 output pin
			REG8(ADDR_REG_GPIO_SEL1) &= ~(1 << 6);
			break;
		case 3:
			lebit--;
		case 6:
			lebit--;
		case 7:
			lebit--;
		case 18:
			lebit--;
		case 19:
			lebit--;
		case 20:
			lebit--;
		case 21:
			lebit--;
		case 22:
			REG8(ADDR_REG_GPIO_SEL2) &= ~(1 << lebit);				//close PWM0 output pin
			break;
		default:
			break;
	}
}